#include "CRenderer.h"

using namespace GameCore;
using namespace Util;

CRenderer* CRenderer::pInstance = NULL;


CRenderer::CRenderer(bool* pDeviceLostFlag_in)
{
	pDeviceLostFlag=pDeviceLostFlag_in;
	pD3DDevice = CCore::getCore()->getDevice();
	pCamera=GameCore::CCore::getCore()->getCamera();
	pWorld=NULL;
	renderEnabled = true;
}

CRenderer::~CRenderer()
{

}

void CRenderer::setD3DParams(const	D3DPRESENT_PARAMETERS d3dpp_in)
{
	d3dpp = d3dpp_in;
}

void CRenderer::setWorld(Content::CWorld* pWorld_in)
{
	pWorld=pWorld_in;
}

CRenderer* CRenderer::getInstance(bool* pDeviceLostFlag_in)
{
	if (pInstance == NULL)
	{
		pInstance = new CRenderer(pDeviceLostFlag_in);
	}
	return pInstance;

}

void CRenderer::run()
{
	while (true)
	{
		{
			boost::mutex::scoped_lock lock(deviceMutex);
			if (renderEnabled)
			{
				if (*pDeviceLostFlag)
				//LOG_WARNING("No device");
				continue;
			}
			else
			{
				continue;
			}

		}


		{
			boost::mutex::scoped_lock lock(pCamera->getMutex());

			const D3DXMATRIX* matView =pCamera->getViewMatrix();;    // the view transform matrix
		
			pD3DDevice->SetTransform(D3DTS_VIEW, matView);    // set the view transform to matView

		// set the projection transform

			pD3DDevice->SetTransform(D3DTS_PROJECTION, CCore::getCore()->getCamera()->getProjectionMatrix()); // set the projection
		}

		pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(100, 100, 100), 1.0f, 0);
		pD3DDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(100, 100, 100), 1.0f, 0);

		pD3DDevice->BeginScene();

		pD3DDevice->SetFVF(CUSTOMFVF);
		HRESULT hr;
		// set the view transform
		if (pWorld == NULL)
		{
			LOG_WARNING("No world");
		}
		else
		{
//			boost::mutex::scoped_lock lock(pCamera->getMutex());
			pWorld->getTerrain()->render();
			pWorld->getPlayer()->render();
			//pWorld->getModel()->render();
		}

		pD3DDevice->EndScene(); 

		hr = pD3DDevice->Present(NULL, NULL, NULL, NULL);
		if( hr == D3DERR_DEVICELOST )
		{
			boost::mutex::scoped_lock lock(deviceMutex);
			*pDeviceLostFlag = true;
		}
	
	}
}

void CRenderer::clean()
{
	pD3DDevice = NULL;
	renderEnabled = false;
}

boost::mutex& CRenderer::getDeviceMutex()
{
	return deviceMutex;
}